package cc.git.liuyan;

import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class SelfLog {
    private static SelfOutPutStream selfOutPutStream = null;
    private static PrintStream selfPrintStream = null;
    private static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static ThreadLocal<Integer> stackDeep = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 1;
        }
    };

    static {
        try {
            File agentLogFile = new File("agent.log");
            selfOutPutStream = new SelfOutPutStream(new FileOutputStream(agentLogFile, true), System.out);
            selfPrintStream = new PrintStream(selfOutPutStream, true);
        } catch (FileNotFoundException e) {
            selfOutPutStream = new SelfOutPutStream(System.out);
            selfPrintStream = new PrintStream(selfOutPutStream, true);
            SelfLog.info(e.getMessage());
            throw new RuntimeException(e);
        }
    }

    public static void printStart(String msg) {
        Integer deep = stackDeep.get();
        String prefixTag = "";
        for (int i = 1; i <= deep; i++) {
            prefixTag = prefixTag + "  ";
        }
        String logMessage = String.format("%sStart%s %s%n", prefixTag, LocalDateTime.now().format(dateTimeFormatter), msg);
        selfOutPutStream.write(logMessage);
        stackDeep.set(deep + 1);
    }

    public static void printEnd(String msg) {
        Integer deep = stackDeep.get();
        String prefixTag = "";
        for (int i = 1; i < deep; i++) {
            prefixTag = prefixTag + "  ";
        }
        String logMessage = String.format("%sEnd%s %s%n", prefixTag, LocalDateTime.now().format(dateTimeFormatter), msg);
        selfOutPutStream.write(logMessage);
        stackDeep.set(deep - 1);
        if (stackDeep.get() == 1) {
            stackDeep.remove();
        }
    }

    public static void info(String msg) {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        StackTraceElement caller = stackTraceElements[2];
        String callerClass = caller.getClassName();
        String callerMethod = caller.getMethodName();
        int callerLine = caller.getLineNumber();
        String logMessage = String.format("%s %s.%s(%s:%d) - %s%n", LocalDateTime.now().format(dateTimeFormatter), callerClass, callerMethod, callerClass, callerLine, msg);
        selfOutPutStream.write(logMessage);
    }

    public static void info(String msg, Exception ex) {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        StackTraceElement caller = stackTraceElements[2];
        String callerClass = caller.getClassName();
        String callerMethod = caller.getMethodName();
        int callerLine = caller.getLineNumber();
        String logMessage = String.format("%s %s.%s(%s:%d) - %s%n", LocalDateTime.now().format(dateTimeFormatter), callerClass, callerMethod, callerClass, callerLine, msg);
        selfOutPutStream.write(logMessage);
        ex.printStackTrace(selfPrintStream);
    }

}
